package com.apexedu.sync.node.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.apexedu.biz.Const;
import com.apexedu.framework.dao.BaseDao;
import com.apexedu.framework.util.DBUtil;
import com.apexedu.framework.util.SeqFactory;
import com.apexedu.identity.entity.TSysMenu;
import com.apexedu.identity.entity.TSysRole;
import com.apexedu.identity.entity.TSysRoleMenu;
import com.apexedu.portal.util.DBMUtil;
import com.apexedu.sync.contant.Constants;
import com.apexedu.sync.engine.ISyncContext;
import com.apexedu.sync.entity.SyncAppModelMsg;
import com.apexedu.sync.exception.AuCSyncException;
import com.apexedu.sync.node.ISyncNode;
import com.apexedu.sys.SysConstant;
import com.apexedu.sys.util.BusinessLogUtil;

/**
 * 同步权限菜单关联关系
 * Created by ly on 2015/1/12.
 */
public class RoleMenuNode extends BaseNode implements ISyncNode {
	@Override
	public void execute(ISyncContext context) throws AuCSyncException {
		DBMUtil dbmUtil = context.getDbmUtil();
		BaseDao baseDao = context.getBaseDao();//多数据源工具类
		String msg;
		try {
			String dbType = context.getDbmUtil().getDbType(); //数据库类型
			String sql = "";
			if (context.isLivebos()) { //livebos系统
				if (Constants.TrueOrFalse.FALSE.equals(context.getAccessAppReg().getTblx())) { //传统模式
					if (Const.DbType.ORACLE.equals(dbType)) {
						sql = "select p.memberid as roleid,substr(f.object,instr(f.object,'.',-1)+1) as menuid" + " from lbfunpermission p, lbfunfactor f where p.funname = f.funname and p.type =1 and p.auditflag =1 " + " group by p.memberid,f.object ";
					} else if (Const.DbType.SQLSERVER.equals(dbType)) {
						sql = "select p.memberid as roleid,subString(f.object, charindex(f.object, '.', -1) + 1,LEN(convert(varchar,f.object))) as menuid"
								+ " from lbfunpermission p, lbfunfactor f where p.funname = f.funname and p.type =1 and p.auditflag =1 " + " group by p.memberid,f.object ";
					}
				} else { //权限树模式
					sql = "select t.memberid as roleid,s.tablename as menuid" + " from lbauth t , ttable s where t.tablename=s.tablename and t.type =1" + " and t.auditflag=1 group by t.memberid, s.tablename ";
				}
			} else { //apexssh系统  TODO 待扩展 第三方
				sql = "select roleid,menuid from t_sys_role_menu";
			}
			List<TSysRoleMenu> listAdd = dbmUtil.queryAllBeanList(sql, TSysRoleMenu.class); //新增集合
			List<TSysRoleMenu> listOld = DBUtil.queryAllBeanList(
					"select * from t_sys_role_menu a" + " where exists (select null from t_sys_role r where r.roleid=a.roleid and r.belongtoapp=?)" + " and exists (select null from t_sys_menu m where m.menuid=a.menuid and m.belongtoapp=?)",
					TSysRoleMenu.class, context.getAppid(), context.getAppid());

			List<TSysRoleMenu> listRemove = new ArrayList<TSysRoleMenu>(); //删除集合

			Map<String, TSysRoleMenu> mapRoleMenuAdd = new HashMap<String, TSysRoleMenu>(); //角色资源关系集合
			//转换为角色权限中心库中的userid和roleid
			for (int i = 0; i < listAdd.size(); i++) {
				TSysRoleMenu add = listAdd.get(i);
				TSysRole role = context.getMapRole().get(add.getRoleid());
				TSysMenu menu = context.getMapMenu().get(add.getMenuid());
				if (role != null && menu != null) { //存在于角色表和菜单资源表中
					add.setId(SeqFactory.getNewSequenceAlone());
					add.setRoleid(role.getRoleid());
					add.setMenuid(menu.getMenuid());
					add.setId(SeqFactory.getNewSequenceAlone());
					mapRoleMenuAdd.put(getKey(add), add);
				} else { //不存在于角色表或菜单资源表中
					listAdd.remove(i);
					i--;
				}
			}

			//校验已存在的与已删除的
			for (TSysRoleMenu old : listOld) {
				TSysRoleMenu add = mapRoleMenuAdd.get(getKey(old));
				if (add != null) {//已存在的从新增集合中删除
					listAdd.remove(add);
					mapRoleMenuAdd.remove(getKey(old));
				} else {//已删除的加入到删除集合中
					listRemove.add(old);
				}
			}

			if (!listAdd.isEmpty()) //保存新增集合
				baseDao.saveAll(listAdd);
			if (!listRemove.isEmpty()) //删除集合
				baseDao.deleteAll(listRemove);

			msg = "插入：" + listAdd.size() + "条，删除：" + listRemove.size() + "条";
			BusinessLogUtil.log(getUserInfo(context), SysConstant.CZDX_T_SYS_ROLE_MENU, Const.LOG_ACTION_UPDATE, "", msg);
			context.getMsg().getListModelMsg().add(new SyncAppModelMsg(Constants.NodeType.ROLE_MENU, msg));
		} catch (Exception e) {
			e.printStackTrace();
			msg = e.getMessage();
			log.error("RoleMenuNode error : " + e);
			context.getMsg().getListModelMsg().add(new SyncAppModelMsg(Constants.NodeType.ROLE_MENU, msg));
			throw new AuCSyncException(AuCSyncException.UNKNOWN_SERVICE_ERROR, msg);
		}
	}

	/**
	 * 获取角色资源关系集合的key值
	 *
	 * @param roleMenu 角色资源关系
	 * @return
	 */
	private String getKey(TSysRoleMenu roleMenu) {
		return roleMenu.getRoleid() + "-" + roleMenu.getMenuid();
	}
}
